package cn.yangsen.simplebeanmanager.bean.html;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
import com.thoughtworks.xstream.io.xml.XppDriver;

public abstract class Element implements Cloneable
{
	private static final XStream xstream = initXStream();

	@Getter
	@Setter
	@XStreamAsAttribute
	private String id;

	@Getter
	@Setter
	@XStreamAsAttribute
	private String title;
	
	@Getter
	@Setter
	@XStreamAsAttribute
	@XStreamAlias("class")
	private String clasz;

	@Getter
	@Setter
	@XStreamImplicit
	private List<Element> elements;

	public void add(Element e)
	{
		if (e == null)
		{
			return;
		}
		if (elements == null)
		{
			elements = new LinkedList<>();
		}
		elements.add(e);
	}

	public void add(Element... es)
	{
		if (es == null)
		{
			return;
		}
		for (Element e : es)
		{
			add(e);
		}
	}

	@Override
	public Element clone()
	{
		Element newOne = null;
		try
		{
			newOne = (Element) super.clone();
		}
		catch (CloneNotSupportedException e)
		{
			e.printStackTrace();
		}
		if (newOne != null)
		{
			List<Element> elements = getElements();
			if (elements != null)
			{
				List<Element> newElements = new ArrayList<>(elements.size());
				for (Element element : elements)
				{
					newElements.add(element.clone());
				}
				newOne.setElements(newElements);
			}
		}
		return newOne;
	}

	public boolean isEmpty()
	{
		return getElements() == null;
	}

	/**
	 * 获取所有元素，包括子元素的子元素
	 * 
	 * @return
	 */
	public Collection<Element> getAllElements()
	{
		List<Element> elements = getElements();
		if (elements == null)
		{
			return null;
		}
		Collection<Element> result = new LinkedList<>();
		result.addAll(elements);
		for (Element element : elements)
		{
			Collection<Element> tempElements = element.getAllElements();
			if (tempElements != null)
			{
				result.addAll(tempElements);
			}
		}
		return result;
	}

	public String toHtml()
	{
		return xstream.toXML(this);
	}

	private static XStream initXStream()
	{
		XStream xstream = new XStream(new XppDriver());
		xstream.processAnnotations(Html.class);
		xstream.processAnnotations(Form.class);
		xstream.processAnnotations(Table.class);
		xstream.processAnnotations(Tr.class);
		xstream.processAnnotations(Td.class);
		xstream.processAnnotations(Input.class);
		xstream.processAnnotations(Radio.class);
		xstream.processAnnotations(Text.class);
		xstream.processAnnotations(Checkbox.class);
		xstream.processAnnotations(Label.class);
		xstream.processAnnotations(A.class);
		xstream.processAnnotations(Hidden.class);
		xstream.processAnnotations(Submit.class);
		xstream.processAnnotations(Button.class);
		xstream.processAnnotations(Textarea.class);
		xstream.processAnnotations(Script.class);
		xstream.processAnnotations(Div.class);
		xstream.processAnnotations(Select.class);
		xstream.processAnnotations(Option.class);
		xstream.processAnnotations(File.class);
		xstream.processAnnotations(Br.class);
		xstream.processAnnotations(P.class);
		return xstream;
	}
}
